﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//using SensorMonitor;


namespace Twin
{
    class SerialIn
    {
        private byte[] buf;
        private int offset;
        private long lastSec;
        //
        //public ArrayList<String> lstIn = new ArrayList<>();
        //
        public SerialIn(){
            buf = new byte[1024 * 8];
            lastSec = 0;
        }
    
        //Clear Rx-buf, if idle for 2s
        //return: true, if clear done
        public bool clearBufAfterIdle(long lastSec){     //(JTextArea win, long lastSec){
            bool f = false;
        
            //一帧必须within 2s
            long now = DateTime.Now.Ticks / 10000;  // System.currentTimeMillis();
            long gap = now - lastSec;               //sensor.dataIn.getLastSec();
            if(gap > 2000){          //超时，2s
                setOffset(0);        //clear buffer
                f = true;
            }
            //win.append("\r\n" + KGet.HHmmSS() + " data received: gap=" + String.valueOf(gap) + "(ms)");
            //win.append(" gap_ahead:" + String.valueOf(gap) + "(ms)");
            setLastSec(now);
            return f;
        }
    
        private byte[] getJStr(byte[] data){
            int i = 0;
            while(i < data.Length){
                if(data[i] == KMsg8.VER_MARK){   // =='J'
                    byte[] JStr = new byte[data.Length - i];
                    Buffer.BlockCopy(data, i, JStr, 0, data.Length - i);   //buf[] = {"J...."}
                    return JStr;
                }
                i++;
            }
            //discard all if no 'J'
            return null;
        }
    
        //==========================================================================
        // append JData[] to buf[]
        // return : offset of buf[]
        //==========================================================================
        public int append(byte[] JData){
            if(JData.Length > 0){   //not empty JData
                Buffer.BlockCopy(JData, 0, buf, offset, JData.Length);
                offset += JData.Length;
            }
            return offset;
        }
    
        
        public byte[] cutOneFrame(){

            int r = KMsg8.isHeadValid(buf);
            switch(r){
                case KMsg8.HEAD_A_R:
                    return buf;

                case KMsg8.HEAD_ERR_VER_MARK:
                    return null;
                    //break;
                case KMsg8.HEAD_ERR_LENGTH_NOT_ENOUGH:
                    return null;
                    //break;

                case KMsg8.HEAD_ERR_CRC:
                    return null;
                    //break;

                case KMsg8.HEAD_OK:
                    int len = KGet.unsignedByte(buf[KMsg8.OFFSET_LEN]) + 1;
                    byte[] frame = new byte[len];
                    Buffer.BlockCopy(buf, 0, frame, 0, len);            //cut-offset
                    //
                    int left = offset - len;
                    if(left >= 0){
                        offset = left;
                        if(left>0){
                            byte[] tmp = new byte[buf.Length];              //自动清零
                            Buffer.BlockCopy(buf, len, tmp, 0, left);
                            Buffer.BlockCopy(tmp, 0, buf, 0, buf.Length);   //前移
                        }
                        return frame;
                    }
                    break;
            }
            offset = 0;
            return null;
        }




        //============================= get/set ====================================
        public int getOffset(){
            return offset;
        }

        private long getLastSec(){
            return lastSec;
        }

        public void setOffset(int offset){
            this.offset = offset;
        }

        private void setLastSec(long lastSec){
            this.lastSec = lastSec;
        }
    


    }

}
